package com.farsight.leo.fssmartlock.activities;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceView;
import android.widget.FrameLayout;

import com.farsight.leo.fssmartlock.Constants;
import com.farsight.leo.fssmartlock.R;
import com.farsight.leo.fssmartlock.bases.BaseActivity;
import com.farsight.leo.fssmartlock.bases.BaseApplication;
import com.farsight.leo.fssmartlock.mqtt.MqttConnection;
import com.farsight.leo.fssmartlock.utils.LogUtils;

import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;

import androidx.annotation.Nullable;
import io.agora.rtc.IRtcEngineEventHandler;
import io.agora.rtc.RtcEngine;
import io.agora.rtc.video.VideoCanvas;
import io.agora.rtc.video.VideoEncoderConfiguration;

public class MonitoringActivity extends BaseActivity {

    private FrameLayout mLocalViewContainer;
    private RtcEngine mRtcEngine;
    private SurfaceView mLocalView;
    private FrameLayout mRemoteViewContainer;
    private SurfaceView mRemoteView;
    private boolean mCallEnd;
    private String mMacAddress;
    private String mChannelId;
    private MqttConnection mMqttConnection;
    private final IRtcEngineEventHandler mRtcEventHandler = new IRtcEngineEventHandler() {
        @Override
        // 注册 onJoinChannelSuccess 回调。
        // 本地用户成功加入频道时，会触发该回调。
        public void onJoinChannelSuccess(String channel, final int uid, int elapsed) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Log.i("agora", "Join channel success, uid: " + (uid & 0xFFFFFFFFL));
                    LogUtils.log("onJoinChannelSuccess maqtt connect start...");
                    mMqttConnection.connect(mCallback);
                }
            });
        }

//        @Override
//        public void onFirstRemoteVideoFrame(final int uid, int width, int height, int elapsed) {
//            super.onFirstRemoteVideoFrame(uid, width, height, elapsed);
//            runOnUiThread(new Runnable() {
//                @Override
//                public void run() {
//                    Log.i("agora", "First remote video decoded, uid: " + (uid & 0xFFFFFFFFL));
//                    setupRemoteVideo(uid);
//                }
//            });
//        }


        @Override
        // 注册 onFirstRemoteVideoDecoded 回调。
        // SDK 接收到第一帧远端视频并成功解码时，会触发该回调。
        // 可以在该回调中调用 setupRemoteVideo 方法设置远端视图。
        public void onFirstRemoteVideoDecoded(final int uid, int width, int height, int elapsed) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Log.i("agora", "First remote video decoded, uid: " + (uid & 0xFFFFFFFFL));
                    setupRemoteVideo(uid);
                }
            });
        }

        @Override
        // 注册 onUserOffline 回调。
        // 远端用户离开频道或掉线时，会触发该回调。
        public void onUserOffline(final int uid, int reason) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Log.i("agora", "User offline, uid: " + (uid & 0xFFFFFFFFL));
                }
            });
        }
    };
    private final MqttConnection.Callback mCallback = new MqttConnection.Callback() {
        @Override
        public void onError(String msg) {
            LogUtils.log(msg);

        }

        @Override
        public void onConnectSuccess(IMqttToken asyncActionToken) {
            try {
                mMqttConnection.publish(mMacAddress, Constants.MQTT_TITLE_REMOTE_VIDEO, genUniqueChannelId());
            } catch (MqttException e) {
                e.printStackTrace();
                LogUtils.log(e.getMessage());
            }

        }

        @Override
        public void connectionLost(Throwable cause) {

        }

        @Override
        public void messageArrived(String topic, MqttMessage message) throws Exception {

        }

        @Override
        public void deliveryComplete(IMqttDeliveryToken token) {

        }
    };


    public static void start(Context context, String devMacAddress) {
        Intent starter = new Intent(context, MonitoringActivity.class);
        starter.putExtra(Constants.KEY_MAC_ADDRESS, devMacAddress);
        context.startActivity(starter);
    }

    @Override
    protected int set_layout_id() {
        return R.layout.activity_monitoring;
    }

    @Override
    protected void initData() {
        mMacAddress = getIntent().getStringExtra(Constants.KEY_MAC_ADDRESS);
        mChannelId = genUniqueChannelId();
        mMqttConnection = new MqttConnection();
        initializeEngine();

    }

    @Override
    protected void initView() {
        mLocalViewContainer = findViewById(R.id.activity_monitoring_fl_local_view_container);
        mRemoteViewContainer = findViewById(R.id.activity_monitoring_fl_remote_view_container);

    }

    @Override
    protected void initListeners() {

    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setupVideoConfig();
        setupLocalVideo();
        joinChannel();
    }

    private String genUniqueChannelId() {
        return "channel1";
    }

    // 初始化 RtcEngine 对象。
    private void initializeEngine() {
        try {
            mRtcEngine = RtcEngine.create(getBaseContext(), getString(R.string.agora_app_id), mRtcEventHandler);
        } catch (Exception e) {
            LogUtils.log(Log.getStackTraceString(e));
            throw new RuntimeException("NEED TO check rtc sdk init fatal error\n" + Log.getStackTraceString(e));
        }
    }

    private void setupVideoConfig() {
        // In simple use cases, we only need to enable video capturing
        // and rendering once at the initialization step.
        // Note: audio recording and playing is enabled by default.
        mRtcEngine.enableVideo();
        mRtcEngine.enableAudio();

        // Please go to this page for detailed explanation
        // https://docs.agora.io/en/Video/API%20Reference/java/classio_1_1agora_1_1rtc_1_1_rtc_engine.html#af5f4de754e2c1f493096641c5c5c1d8f
        mRtcEngine.setVideoEncoderConfiguration(new VideoEncoderConfiguration(
                VideoEncoderConfiguration.VD_640x360,
                VideoEncoderConfiguration.FRAME_RATE.FRAME_RATE_FPS_15,
                VideoEncoderConfiguration.STANDARD_BITRATE,
                VideoEncoderConfiguration.ORIENTATION_MODE.ORIENTATION_MODE_FIXED_PORTRAIT));
    }

    private void setupLocalVideo() {
        // 创建 SurfaceView 对象。
        mLocalView = RtcEngine.CreateRendererView(getBaseContext());
        mLocalView.setZOrderMediaOverlay(true);
        mLocalViewContainer.addView(mLocalView);
        // 设置本地视图。
        VideoCanvas localVideoCanvas = new VideoCanvas(mLocalView, VideoCanvas.RENDER_MODE_HIDDEN, 0);
        mRtcEngine.setupLocalVideo(localVideoCanvas);
    }

    private void joinChannel() {
        // 使用 Token 加入频道。
        mRtcEngine.joinChannel(null, mChannelId, "Extra Optional Data", 0);
    }

    private void setupRemoteVideo(int uid) {
        // 创建一个 SurfaceView 对象。
        mRemoteView = RtcEngine.CreateRendererView(getBaseContext());
        mRemoteViewContainer.addView(mRemoteView);
        // 设置远端视图。
        mRtcEngine.setupRemoteVideo(new VideoCanvas(mRemoteView, VideoCanvas.RENDER_MODE_HIDDEN, uid));

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mMqttConnection.disconnect();
        if (!mCallEnd) {
            leaveChannel();
        }
        RtcEngine.destroy();

    }

    private void leaveChannel() {
        // 离开当前频道。
        mRtcEngine.leaveChannel();
        mCallEnd = true;
    }
}
